#ifndef __CLI_PARSE__UTIL_H__
#define __CLI_PARSE__UTIL_H__

#include "math.h" // sqrt (...)

bool ApplyTexture        (unsigned int idx);
bool ApplyFlatTexture    (unsigned int idx);

bool ApplyEffectTexture  (unsigned int idx);
bool ApplyAnimatedEffect (unsigned int idx, unsigned int frame);

bool LoadTexture         (const unsigned int index, const bool& bForceLoad);
bool LoadFlatTexture     (const unsigned int index, const bool& bForceLoad);
bool LoadEffectTexture   (const unsigned int index);


namespace cli_parse
{
  void DrawPostProcessing (void);
};

void DrawDebugTile       (int id, int type); // Types: 0->tex, 1->flat, 2->vfx

/* Together with DrawDebugTile (...), these two functions will cycle up or down
     through the list of known visual effects, for debugging.

    Any unloadable visual effect is logged, and the functions attempt to load
      the next highest or lowest effect, until they hit the high- or low-end
        of the vfx array...
*/
int  SelectNextVFX       (int id);
int  SelectPrevVFX       (int id);


class OpenALBuffer;

/* TODO: This should store created sounds in an array... */
OpenALBuffer* MakeSoundAL (Underlight::id_t sound_id);



class eInput;
class e3dRenderContext;

namespace Underlight
{
  class Room;
  class Sector;
  class Line;

  Room*   room_from_sector (Sector* sector);
  Room*   room_from_pos    (float x, float y);

  Sector* get_sector       (Room*   room, int id);
  void    DumpSector       (Sector* sector);

  Line*   GetLine          (Room*   room, int line_num);
  void    DumpLine         (Line*   line);

  float   UnderlightAngle  (short angle);

  PickingData Pick (eInput* input, e3dRenderContext* rc);
};

// The true distance between two points
inline float
fdist (float x1, float y1, float x2, float y2)
{
#define DOUBLE_PRECISION
#ifdef DOUBLE_PRECISION
  double dx,dy;
  dx = (x1 - x2);
  dy = (y1 - y2);

  double sum = (dx * dx) + (dy * dy);

  double result = sqrt (sum);

  float float_result = (float)result;
#else
  float fx,fy;
  fx = (x1 - x2);
  fy = (y1 - y2);

  float sum = (fx * fx) + (fy * fy);

  float float_result = sqrtf (sum);
#endif

  //if (float_result < 0) 
  {
    //	eTB_Printf("NEGATIVE DISTANCE!!!!\n");
    //	eTB_Printf("x1: %f y1: %f  x2: %f y2: %f\n", x1, y1, x2, y2);
    //	eTB_Printf("dx: %e dy: %e sum: %e result: %e float result: %f\n", dx, dy, sum, result, float_result); 
  }

  return float_result;
}

inline bool
CloseEnough (float a, float b)
{
  if (a == b)
    return true;

  //
  // TODO: Use this to weld shared vertices
  //
  if (a < b && a + 0.0001f >= b) {
    //eTB_Printf ("CloseEnough: 0\n");
    return true;
  }
  if (b < a && b + 0.0001f >= a) {
    //eTB_Printf ("CloseEnough: 1\n");
    return true;
  }

  return false;
}

bool
SaveTGAFile ( const char*          filename,
              const short int&     width,
              const short int&     height,
              const unsigned char& bits,
              unsigned char*       imageData );

#endif /* __CLI_PARSE__UTIL_H__ */
